package com.example.gbuffer.Component.Framebuffer;
import com.example.gbuffer.Utils.OpenGLUtils;

import android.opengl.GLES32;
import android.util.Log;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;

public class GeoFramebuffer extends Framebuffer{

    private int[] m_gPosition_tex = new int[1];
    private int[] m_gNormaltex = new int[1];
    private int[] m_gColorSpec_tex = new int[1];


    private int[] m_render_buffer = new int[1];

    private int m_width;
    private int m_height;
    private String LOG_TAG = "GeoFramebuffer";

    public enum BufferType{
        POSITION_BUFFER,
        NORMAL_BUFFER,
        COLOR_SPEC_BUFFER
    }

    public int getBufferTextureId(BufferType type) {
        if (type == BufferType.POSITION_BUFFER) {
            return m_gPosition_tex[0];
        }
        else if( type == BufferType.NORMAL_BUFFER) {
            return m_gNormaltex[0];
        }
        else if( type == BufferType.COLOR_SPEC_BUFFER) {
            return m_gColorSpec_tex[0];
        }
        return -1;
    }


    public GeoFramebuffer(int width, int height){
        super();

        if ( !init(width, height) ) {
            Log.w(LOG_TAG, "init geo framebuffer failed.");
        }
    }


    protected boolean init(int width, int height) {

        m_width = width;
        m_height = height;

        GLES32.glGenFramebuffers(1, m_buffer, 0);
        GLES32.glBindFramebuffer(GLES32.GL_FRAMEBUFFER, m_buffer[0]);

//        // 1. 创建 ByteBuffer 并填充白色数据 (RGBA = {1.0, 1.0, 1.0, 1.0})
//        int pixelSize = 4; // RGBA, so 4 bytes per pixel
//        ByteBuffer buffer = ByteBuffer.allocateDirect(m_width * m_height * pixelSize * 4)
//                .order(ByteOrder.nativeOrder());
//
//        for (int i = 0; i < width * height; i++) {
//            buffer.putFloat(1.0f); // R
//            buffer.putFloat(0.0f); // G
//            buffer.putFloat(0.5f); // B
//            buffer.putFloat(1.0f); // A
//        }
//        buffer.rewind(); // 准备读取数据

        // - 位置颜色缓冲
        GLES32.glGenTextures(1, m_gPosition_tex, 0);
        GLES32.glBindTexture(GLES32.GL_TEXTURE_2D, m_gPosition_tex[0]);
        GLES32.glTexImage2D(GLES32.GL_TEXTURE_2D, 0, GLES32.GL_RGB16F, m_width, m_height, 0, GLES32.GL_RGB, GLES32.GL_FLOAT, null);
        GLES32.glTexParameteri(GLES32.GL_TEXTURE_2D, GLES32.GL_TEXTURE_MIN_FILTER, GLES32.GL_LINEAR);
        GLES32.glTexParameteri(GLES32.GL_TEXTURE_2D, GLES32.GL_TEXTURE_MAG_FILTER, GLES32.GL_LINEAR);
        GLES32.glFramebufferTexture2D(GLES32.GL_FRAMEBUFFER, GLES32.GL_COLOR_ATTACHMENT0, GLES32.GL_TEXTURE_2D, m_gPosition_tex[0], 0);

        // - 法线颜色缓冲
        GLES32.glGenTextures(1, m_gNormaltex, 0);
        GLES32.glBindTexture(GLES32.GL_TEXTURE_2D, m_gNormaltex[0]);
        GLES32.glTexImage2D(GLES32.GL_TEXTURE_2D, 0, GLES32.GL_RGB16F, m_width, m_height, 0, GLES32.GL_RGB, GLES32.GL_FLOAT, null);
        GLES32.glTexParameteri(GLES32.GL_TEXTURE_2D, GLES32.GL_TEXTURE_MIN_FILTER, GLES32.GL_NEAREST);
        GLES32.glTexParameteri(GLES32.GL_TEXTURE_2D, GLES32.GL_TEXTURE_MAG_FILTER, GLES32.GL_NEAREST);
        GLES32.glFramebufferTexture2D(GLES32.GL_FRAMEBUFFER, GLES32.GL_COLOR_ATTACHMENT1, GLES32.GL_TEXTURE_2D, m_gNormaltex[0], 0);

        // - 颜色 + 镜面颜色缓冲
        GLES32.glGenTextures(1, m_gColorSpec_tex, 0);
        GLES32.glBindTexture(GLES32.GL_TEXTURE_2D, m_gColorSpec_tex[0]);
        GLES32.glTexImage2D(GLES32.GL_TEXTURE_2D, 0, GLES32.GL_RGBA16F, m_width, m_height, 0, GLES32.GL_RGBA, GLES32.GL_FLOAT, null);
        GLES32.glTexParameteri(GLES32.GL_TEXTURE_2D, GLES32.GL_TEXTURE_MIN_FILTER, GLES32.GL_NEAREST);
        GLES32.glTexParameteri(GLES32.GL_TEXTURE_2D, GLES32.GL_TEXTURE_MAG_FILTER, GLES32.GL_NEAREST);
        GLES32.glFramebufferTexture2D(GLES32.GL_FRAMEBUFFER, GLES32.GL_COLOR_ATTACHMENT2, GLES32.GL_TEXTURE_2D, m_gColorSpec_tex[0], 0);

        // - 深度缓冲
        GLES32.glGenRenderbuffers(1, m_render_buffer, 0);
        GLES32.glBindRenderbuffer(GLES32.GL_RENDERBUFFER, m_render_buffer[0]);
        GLES32.glRenderbufferStorage(GLES32.GL_RENDERBUFFER, GLES32.GL_DEPTH_COMPONENT24, m_width, m_height);
        GLES32.glFramebufferRenderbuffer(GLES32.GL_FRAMEBUFFER, GLES32.GL_DEPTH_ATTACHMENT, GLES32.GL_RENDERBUFFER, m_render_buffer[0]);

        GLES32.glBindFramebuffer(GLES32.GL_FRAMEBUFFER, 0);
        GLES32.glBindTexture(GLES32.GL_TEXTURE_2D, 0);
        return OpenGLUtils.checkFramebufferStatus();
    }

    @Override
    public void bind() {

        GLES32.glBindFramebuffer(GLES32.GL_FRAMEBUFFER, m_buffer[0]);

        // - 告诉OpenGL我们将要使用(帧缓冲的)哪种颜色附件来进行渲染
        IntBuffer attachments = IntBuffer.wrap(new int[]{
                GLES32.GL_COLOR_ATTACHMENT0,
                GLES32.GL_COLOR_ATTACHMENT1,
                GLES32.GL_COLOR_ATTACHMENT2,
        });
        attachments.position(0);
        GLES32.glDrawBuffers(attachments.capacity(), attachments);
    }
}
